package com.sanley.coronavirus.config;

import com.sanley.coronavirus.common.security.AuthenticationFailHandler;
import com.sanley.coronavirus.common.security.AuthenticationSuccessHandler;
import com.sanley.coronavirus.common.security.JWTAuthenticationFilter;
import com.sanley.coronavirus.common.security.MyAccessDenied;
import com.sanley.coronavirus.common.utils.JwtUtils;
import com.sanley.coronavirus.service.MyUserDetailService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.annotation.Bean;
import org.springframework.security.authentication.dao.DaoAuthenticationProvider;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.AuthenticationEntryPoint;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.CorsConfigurationSource;
import org.springframework.web.cors.CorsUtils;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;

import java.util.Collections;

@EnableWebSecurity
public class MySecurityConfig extends WebSecurityConfigurerAdapter {
    @Autowired
    private MyUserDetailService myUserDetailService;

    @Autowired
    @Qualifier("authenticationSuccessHandler")
    private AuthenticationSuccessHandler successHandler;

    @Autowired
    @Qualifier("authenticationFailHandler")
    private AuthenticationFailHandler failHandler;

    @Autowired
    @Qualifier("authenticationEntryPointImpl")
    private AuthenticationEntryPoint entryPoint;

    @Autowired
    private MyAccessDenied myAccessDenied;

    @Bean
    public PasswordEncoder passwordEncoder() {
        return new BCryptPasswordEncoder();   // 使用 BCrypt 加密
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {
        http.sessionManagement()
                .sessionCreationPolicy(SessionCreationPolicy.STATELESS)
                .and()        //关闭csrf保护功能
                .csrf().disable()
                .cors().and()
                .authorizeRequests().requestMatchers(CorsUtils::isPreFlightRequest).authenticated()
                //定制请求的授权规则
                .antMatchers(permitUrl()).permitAll()
                .antMatchers("/report/user/**", "/dashboard/**", "/checkOut/**", "/notification/*", "/touch/add").hasRole("User")
                .antMatchers("/report/**", "/manager/**/", "/patient/**", "/touch/**", "/cure/**", "/dead/**/").hasRole("Admin")
                .anyRequest().authenticated()
                .and().formLogin().loginProcessingUrl("/login")
                .successHandler(successHandler)
                .failureHandler(failHandler)
                .and().logout().logoutUrl("/logout").logoutSuccessUrl("/logoutProcess")
                .and().exceptionHandling().authenticationEntryPoint(entryPoint);

        http.exceptionHandling().accessDeniedHandler(myAccessDenied);
        http.addFilterBefore(jwtAuthenticationFilter(), UsernamePasswordAuthenticationFilter.class);
//        http.logout().logoutUrl("/logout").logoutSuccessUrl("/login");
        //开启记住我功能
    }

    //定制认证页面
    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(myUserDetailService);
        auth.authenticationProvider(authenticationProvider());
    }

    public DaoAuthenticationProvider authenticationProvider() {
        DaoAuthenticationProvider authenticationProvider = new DaoAuthenticationProvider();
        authenticationProvider.setPasswordEncoder(passwordEncoder());
        authenticationProvider.setUserDetailsService(myUserDetailService);
        return authenticationProvider;
    }

    @Bean
    public JwtUtils jwtUtils() {
        return new JwtUtils();
    }

    @Bean
    public JWTAuthenticationFilter jwtAuthenticationFilter() throws Exception {
        return new JWTAuthenticationFilter(authenticationManager());
    }

    @Bean
    public String[] permitUrl() {
        return new String[]{"/login", "/register", "/addUser", "/index", "/v2/api-docs", "/swagger-resources/configuration/ui",
                "/swagger-resources", "/swagger-resources/configuration/security", "/swagger-ui.html",
                "/webjars/**"};
    }

}
